﻿#include "PageService.h"
#include "Notification.h"
#include <QDebug>
#include <QInputDialog>
#include <QMessageBox>  // 保留用于 question 对话框
#include <QFile>
#include <QTimer>
#include <QFileInfoList>
#include <QDir>

PageService::PageService() : QObject(nullptr)
{
    // 创建定时器
    m_refreshTimer = new QTimer(this);
    connect(m_refreshTimer, &QTimer::timeout, this, &PageService::loadRecentItems);

    // 默认每 60 秒刷新一次
    m_refreshTimer->start(60000);
}

PageService::~PageService()
{
}

void PageService::init()
{
    // 初始化数据库
    if (!DbMgr::GetInstance()->init("page_service.db")) {
        qCritical() << "数据库初始化失败";
        return;
    }

    qDebug() << "PageService数据库初始化成功";
    createTables();
}

void PageService::setCodeEditor(CodeEditor* editor)
{
    if (m_codeEditor) {
        disconnect(m_codeEditor, &CodeEditor::addLabelClicked,
            this, &PageService::onAddLabelClicked);
    }

    m_codeEditor = editor;

    if (m_codeEditor) {
        connect(m_codeEditor, &CodeEditor::addLabelClicked,
            this, &PageService::onAddLabelClicked);
        qDebug() << "CodeEditor已设置";
    }
}

void PageService::setRecentList(RecentList* recentList)
{
    if (m_recentList) {
        disconnect(m_recentList, &RecentList::itemClicked,
            this, &PageService::onRecentItemClicked);
        disconnect(m_recentList, &RecentList::itemDeleteRequested,
            this, &PageService::onRecentItemDeleteRequested);
    }

    m_recentList = recentList;

    if (m_recentList) {
        connect(m_recentList, &RecentList::itemClicked,
            this, &PageService::onRecentItemClicked);
        connect(m_recentList, &RecentList::itemDeleteRequested,
            this, &PageService::onRecentItemDeleteRequested);
        qDebug() << "RecentList已设置";
    }
}

void PageService::setLabelList(LabelList* labelList)
{
    if (m_labelList) {
        disconnect(m_labelList, &LabelList::itemClicked,
            this, &PageService::onLabelItemClicked);
    }

    m_labelList = labelList;

    if (m_labelList) {
        connect(m_labelList, &LabelList::itemClicked,
            this, &PageService::onLabelItemClicked);
        qDebug() << "LabelList已设置";
    }
}

void PageService::createTables()
{
    QString createFileInfoTable = R"(
        CREATE TABLE IF NOT EXISTS file_info (
            file_id TEXT PRIMARY KEY,
            file_name TEXT NOT NULL,
            file_path TEXT NOT NULL UNIQUE,
            last_modify TEXT NOT NULL
        )
    )";

    QString createLabelItemTable = R"(
        CREATE TABLE IF NOT EXISTS label_item (
            label_id TEXT PRIMARY KEY,
            file_id TEXT NOT NULL,
            label_name TEXT NOT NULL,
            row_number INTEGER NOT NULL,
            FOREIGN KEY (file_id) REFERENCES file_info(file_id) ON DELETE CASCADE
        )
    )";

    QString createRecentItemTable = R"(
        CREATE TABLE IF NOT EXISTS recent_item (
            recent_id TEXT PRIMARY KEY,
            file_id TEXT NOT NULL,
            access_time TEXT NOT NULL,
            FOREIGN KEY (file_id) REFERENCES file_info(file_id) ON DELETE CASCADE
        )
    )";

    QString createLastOpenedTable = R"(
        CREATE TABLE IF NOT EXISTS last_opened_file (
            id INTEGER PRIMARY KEY DEFAULT 1,
            file_id TEXT NOT NULL,
            FOREIGN KEY (file_id) REFERENCES file_info(file_id) ON DELETE SET NULL,
            CONSTRAINT single_row CHECK (id = 1)
        )
    )";

    QString createFilePathIndex = R"(
        CREATE INDEX IF NOT EXISTS idx_file_path ON file_info(file_path)
    )";

    QString createAccessTimeIndex = R"(
        CREATE INDEX IF NOT EXISTS idx_access_time ON recent_item(access_time DESC)
    )";

    DbMgr::GetInstance()->executeSql(createFileInfoTable, [](const DbResult& result) {
        if (result.isSuccess()) {
            qDebug() << "file_info表创建成功";
        }
        else {
            qWarning() << "创建file_info表失败:" << result.error();
        }
        });

    DbMgr::GetInstance()->executeSql(createLabelItemTable, [](const DbResult& result) {
        if (result.isSuccess()) {
            qDebug() << "label_item表创建成功";
        }
        else {
            qWarning() << "创建label_item表失败:" << result.error();
        }
        });

    DbMgr::GetInstance()->executeSql(createRecentItemTable, [](const DbResult& result) {
        if (result.isSuccess()) {
            qDebug() << "recent_item表创建成功";
        }
        else {
            qWarning() << "创建recent_item表失败:" << result.error();
        }
        });

    DbMgr::GetInstance()->executeSql(createLastOpenedTable, [](const DbResult& result) {
        if (result.isSuccess()) {
            qDebug() << "last_opened_file表创建成功";
        }
        else {
            qWarning() << "创建last_opened_file表失败:" << result.error();
        }
        });

    DbMgr::GetInstance()->executeSql(createFilePathIndex, [](const DbResult& result) {
        if (result.isSuccess()) {
            qDebug() << "文件路径索引创建成功";
        }
        });

    DbMgr::GetInstance()->executeSql(createAccessTimeIndex, [](const DbResult& result) {
        if (result.isSuccess()) {
            qDebug() << "访问时间索引创建成功";
        }
        });
}

void PageService::loadRecentItems()
{
    if (!m_recentList) {
        qWarning() << "RecentList未设置";
        return;
    }

    qDebug() << "开始加载最近访问列表";

    QString sql = R"(
        SELECT r.recent_id, r.file_id, r.access_time, f.file_name, f.file_path
        FROM recent_item r
        JOIN file_info f ON r.file_id = f.file_id
        ORDER BY r.access_time DESC
        LIMIT 50
    )";

    DbMgr::GetInstance()->executeSql(sql, [this](const DbResult& result) {
        if (!result.isSuccess()) {
            qWarning() << "加载最近访问记录失败:" << result.error();
            return;
        }

        qDebug() << "查询到" << result.data().size() << "条最近访问记录";

        QMetaObject::invokeMethod(this, [this, result]() {
            if (!m_recentList) {
                qWarning() << "RecentList已销毁，终止加载";
                return;
            }

            m_recentList->clear();

            for (const QVariantMap& row : result.data()) {
                QString fileName = row["file_name"].toString();
                QString filePath = row["file_path"].toString();
                QString accessTime = row["access_time"].toString();
                QDateTime dt = QDateTime::fromString(accessTime, Qt::ISODate);

                RecentItem* item = new RecentItem(fileName, dt, m_recentList->parentWidget());
                item->setFilePath(filePath);
                m_recentList->addItem(item);
            }

            emit recentItemsLoaded();
            qDebug() << "最近访问列表加载完成（主线程）";
            }, Qt::QueuedConnection);
        });
}

void PageService::loadLabelsForFile(const QUuid& fileId)
{
    if (!m_labelList) {
        qWarning() << "LabelList未设置";
        return;
    }

    if (fileId.isNull()) {
        qWarning() << "文件ID为空，无法加载标签";
        QMetaObject::invokeMethod(this, [this]() {
            if (m_labelList) m_labelList->clear();
            }, Qt::QueuedConnection);
        return;
    }

    qDebug() << "开始加载文件标签，文件ID:" << fileId.toString();

    QString condition = QString("file_id = '%1'").arg(fileId.toString());

    DbMgr::GetInstance()->select("label_item", "*", condition, "",
        [this](const DbResult& result) {
            if (!result.isSuccess()) {
                qWarning() << "加载标签失败:" << result.error();
                return;
            }

            qDebug() << "查询到" << result.data().size() << "个标签";

            QMetaObject::invokeMethod(this, [this, result]() {
                if (!m_labelList) {
                    qWarning() << "LabelList已销毁，终止加载标签";
                    return;
                }

                m_labelList->clear();
                for (const QVariantMap& row : result.data()) {
                    QUuid labelId = QUuid(row["label_id"].toString());
                    QString labelName = row["label_name"].toString();
                    int rowNumber = row["row_number"].toInt();

                    LabelItem* item = new LabelItem(labelName, rowNumber, m_labelList->parentWidget());
                    item->setLabelId(labelId);
                    connect(item, &LabelItem::deleteRequested, this, &PageService::onLabelDeleteRequested);
                    connect(item, &LabelItem::renameRequested, this, &PageService::onLabelRenameRequested);
                    connect(item, &LabelItem::changeLineRequested, this, &PageService::onChangeLineRequested);
                    m_labelList->addItem(item);
                }

                emit labelsLoaded();
                qDebug() << "标签列表加载完成（主线程）";
                }, Qt::QueuedConnection);
        });
}

// 使用异步文件读取
void PageService::openFile(const QString& filePath)
{
    if (!m_codeEditor) {
        qWarning() << "CodeEditor未设置";
        emit fileOpenCompleted();
        return;
    }

    // 并发控制：防止重复打开
    bool expected = false;
    if (!m_isOpeningFile.compare_exchange_strong(expected, true)) {
        qDebug() << "文件正在打开中，新请求将覆盖:" << filePath;
        m_pendingFilePath = filePath;  // 保存最新的请求
        return;
    }

    qDebug() << "准备异步打开文件:" << filePath;

    // 检查文件是否存在
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        // 使用 Notification 替代 QMessageBox::warning
        if (m_notification) {
            m_notification->Push(
                Notify_Type_Error,
                Pos_Bottom_Right,
                "错误",
                "文件不存在: " + filePath,
                3000
            );
        }
        m_isOpeningFile = false;
        emit fileOpenCompleted();
        return;
    }

    // 检查文件大小（限制超大文件）
    qint64 fileSize = fileInfo.size();
    if (fileSize > 100 * 1024 * 1024) {  // 100MB
        // 保留 QMessageBox::question，因为需要用户确认
        QMessageBox::StandardButton reply = QMessageBox::question(
            nullptr,
            "警告",
            QString("文件较大（%1 MB），可能需要较长时间打开，是否继续？")
            .arg(fileSize / 1024.0 / 1024.0, 0, 'f', 2),
            QMessageBox::Yes | QMessageBox::No
        );

        if (reply != QMessageBox::Yes) {
            m_isOpeningFile = false;
            emit fileOpenCompleted();
            return;
        }
    }

    // 使用异步读取文件
    TextFileUtils::readFileAsync(filePath,
        [this, filePath, fileInfo](const TextFileUtils::ReadResult& result) {
            // 回调在主线程执行

            if (!result.success) {
                // 使用 Notification 替代 QMessageBox::warning
                if (m_notification) {
                    m_notification->Push(
                        Notify_Type_Error,
                        Pos_Bottom_Right,
                        "失败",
                        "读取文件失败: " + result.errorMessage,
                        3000
                    );
                }
                qWarning() << "读取文件失败:" << filePath << result.errorMessage;
                m_isOpeningFile = false;
                emit fileOpenCompleted();

                // 检查是否有待处理的文件
                if (!m_pendingFilePath.isEmpty()) {
                    QString pending = m_pendingFilePath;
                    m_pendingFilePath.clear();
                    openFile(pending);
                }
                return;
            }

            if (!m_codeEditor) {
                qWarning() << "CodeEditor已销毁，无法打开文件";
                m_isOpeningFile = false;
                emit fileOpenCompleted();
                return;
            }

            // 设置编辑器内容（主线程，UI操作）
            m_codeEditor->setText(result.content, result.detectedEncoding);
            qDebug() << "文件内容已设置到CodeEditor，编码:"
                << TextFileUtils::encodingToString(result.detectedEncoding);

            // 处理数据库操作
            handleFileOpenedInDatabase(filePath, fileInfo);

            // 解锁
            m_isOpeningFile = false;

            // 检查是否有待处理的文件
            if (!m_pendingFilePath.isEmpty()) {
                QString pending = m_pendingFilePath;
                m_pendingFilePath.clear();
                qDebug() << "处理待打开的文件:" << pending;
                openFile(pending);
            }
        },
        TextFileUtils::AUTO_DETECT,
        this  // context：当PageService销毁时自动取消
    );
}

// 提取数据库操作到独立方法
void PageService::handleFileOpenedInDatabase(const QString& filePath, const QFileInfo& fileInfo)
{
    QString fileName = fileInfo.fileName();
    QDateTime lastModify = fileInfo.lastModified();
    QString condition = QString("file_path = '%1'").arg(filePath);

    DbMgr::GetInstance()->select("file_info", "*", condition, QString(),
        [this, filePath, fileName, lastModify](const DbResult& result) {
            QUuid fileId;
            if (result.isSuccess() && !result.data().isEmpty()) {
                // 文件已存在，更新
                fileId = QUuid(result.data().first()["file_id"].toString());
                qDebug() << "文件已存在，ID:" << fileId.toString();

                QVariantMap values;
                values["last_modify"] = lastModify.toString(Qt::ISODate);
                QString updateCondition = QString("file_id = '%1'").arg(fileId.toString());

                DbMgr::GetInstance()->update("file_info", values, updateCondition,
                    [this, fileId, filePath](const DbResult& updateResult) {
                        if (updateResult.isSuccess()) {
                            qDebug() << "文件信息更新成功";
                        }
                        m_currentFileId = fileId;
                        m_currentFilePath = filePath;
                        ensureRecentItemExists(fileId);
                        loadLabelsForFile(fileId);
                        emit fileLoaded(filePath);
                        saveLastOpenedFileId(fileId);
                        emit fileOpenCompleted();
                    });
            }
            else {
                // 创建新文件记录
                fileId = QUuid::createUuid();
                qDebug() << "创建新文件记录，ID:" << fileId.toString();

                QVariantMap values;
                values["file_id"] = fileId.toString();
                values["file_name"] = fileName;
                values["file_path"] = filePath;
                values["last_modify"] = lastModify.toString(Qt::ISODate);

                DbMgr::GetInstance()->insert("file_info", values,
                    [this, fileId, filePath](const DbResult& insertResult) {
                        if (insertResult.isSuccess()) {
                            qDebug() << "文件信息保存成功";
                        }
                        else {
                            qWarning() << "文件信息保存失败:" << insertResult.error();
                        }
                        m_currentFileId = fileId;
                        m_currentFilePath = filePath;
                        updateRecentAccess(fileId);
                        loadLabelsForFile(fileId);
                        emit fileLoaded(filePath);
                        saveLastOpenedFileId(fileId);
                        emit fileOpenCompleted();
                    });
            }
        });
}

void PageService::openFolder(const QString& folderPath)
{
    QDir dir(folderPath);
    if (!dir.exists()) {
        // 使用 Notification 替代 QMessageBox::warning
        if (m_notification) {
            m_notification->Push(
                Notify_Type_Error,
                Pos_Bottom_Right,
                "错误",
                "文件夹不存在: " + folderPath,
                3000
            );
        }
        qWarning() << "文件夹不存在:" << folderPath;
        return;
    }

    qDebug() << "开始加载文件夹:" << folderPath;

    QStringList filters;
    filters << "*.txt" << "*.cpp" << "*.h" << "*.c" << "*.cc" << "*.cxx"
        << "*.py" << "*.java" << "*.js" << "*.ts" << "*.jsx" << "*.tsx"
        << "*.html" << "*.htm" << "*.css" << "*.scss" << "*.less"
        << "*.json" << "*.xml" << "*.yaml" << "*.yml"
        << "*.md" << "*.markdown" << "*.rst"
        << "*.sh" << "*.bat" << "*.ps1"
        << "*.sql" << "*.go" << "*.rs" << "*.php"
        << "*.cs" << "*.vb" << "*.swift" << "*.kt";

    QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files | QDir::NoDotAndDotDot, QDir::Name);

    if (fileList.isEmpty()) {
        // 使用 Notification 替代 QMessageBox::information
        if (m_notification) {
            m_notification->Push(
                Notify_Type_Information,
                Pos_Bottom_Right,
                "提示",
                "文件夹中没有找到支持的文件类型",
                3000
            );
        }
        qDebug() << "文件夹为空或没有支持的文件";
        return;
    }

    qDebug() << "找到" << fileList.count() << "个文件";

    int* processedCount = new int(0);
    int totalCount = fileList.count();

    for (const QFileInfo& fileInfo : fileList) {
        QString filePath = fileInfo.absoluteFilePath();
        ensureFileInDatabase(filePath, processedCount, totalCount);
    }
}

void PageService::onRecentItemClicked(const QString& fileName)
{
    QMutexLocker locker(&m_mutex);
    if (m_isProcessing) {
        qDebug() << "正在处理前一个点击事件，忽略当前点击:" << fileName;
        return;
    }
    m_isProcessing = true;
    locker.unlock();

    qDebug() << "点击最近访问项:" << fileName;

    QString condition = QString("file_name = '%1'").arg(fileName);

    DbMgr::GetInstance()->select("file_info", "file_path", condition, QString(),
        [this, fileName](const DbResult& result) {
            if (result.isSuccess() && !result.data().isEmpty()) {
                QString filePath = result.data().first()["file_path"].toString();
                qDebug() << "找到文件路径:" << filePath;

                QMetaObject::Connection* conn = new QMetaObject::Connection();
                *conn = connect(this, &PageService::fileOpenCompleted, this, [this, conn]() {
                    QMutexLocker locker(&m_mutex);
                    m_isProcessing = false;
                    disconnect(*conn);
                    delete conn;
                    }, Qt::QueuedConnection);

                openFile(filePath);
            }
            else {
                QMetaObject::invokeMethod(this, [this, fileName]() {
                    // 使用 Notification 替代 QMessageBox::warning
                    if (m_notification) {
                        m_notification->Push(
                            Notify_Type_Warning,
                            Pos_Bottom_Right,
                            "失败",
                            "未找到文件: " + fileName,
                            3000
                        );
                    }
                    QMutexLocker locker(&m_mutex);
                    m_isProcessing = false;
                    qWarning() << "未找到文件:" << fileName;
                    }, Qt::QueuedConnection);
            }
        });
}

void PageService::onRecentItemDeleteRequested(const QString& filePath)
{
    qDebug() << "请求删除最近访问项，文件路径:" << filePath;

    QMetaObject::invokeMethod(this, [this, filePath]() {
        if (!m_recentList) return;

        // 保留 QMessageBox::question，因为需要用户确认
        QMessageBox::StandardButton reply = QMessageBox::question(
            nullptr,
            "确认删除",
            QString("确定要从最近访问列表中移除\n\"%1\"\n吗？\n\n注意：这不会删除实际文件，只会从列表中移除。").arg(filePath),
            QMessageBox::Yes | QMessageBox::No
        );

        if (reply != QMessageBox::Yes) {
            qDebug() << "取消删除";
            return;
        }

        QString condition = QString("file_path = '%1'").arg(filePath);
        DbMgr::GetInstance()->select("file_info", "file_id", condition, QString(),
            [this, filePath](const DbResult& result) {
                if (!result.isSuccess() || result.data().isEmpty()) {
                    QMetaObject::invokeMethod(this, [this, filePath]() {
                        // 使用 Notification 替代 QMessageBox::warning
                        if (m_notification) {
                            m_notification->Push(
                                Notify_Type_Error,
                                Pos_Bottom_Right,
                                "失败",
                                "未找到该文件的记录",
                                3000
                            );
                        }
                        }, Qt::QueuedConnection);
                    qWarning() << "未找到文件记录:" << filePath;
                    return;
                }

                QUuid fileId = QUuid(result.data().first()["file_id"].toString());
                qDebug() << "找到文件ID:" << fileId.toString();

                QString deleteCondition = QString("file_id = '%1'").arg(fileId.toString());
                DbMgr::GetInstance()->deleteRecord("recent_item", deleteCondition,
                    [this, filePath](const DbResult& deleteResult) {
                        if (deleteResult.isSuccess()) {
                            qDebug() << "最近访问记录删除成功:" << filePath;
                            QMetaObject::invokeMethod(this, [this]() {
                                if (m_recentList) loadRecentItems();
                                }, Qt::QueuedConnection);

                            // 使用 Notification 替代 QMessageBox::information
                            QMetaObject::invokeMethod(this, [this]() {
                                if (m_notification) {
                                    m_notification->Push(
                                        Notify_Type_Success,
                                        Pos_Bottom_Right,
                                        "成功",
                                        "已从最近访问列表中移除",
                                        2000
                                    );
                                }
                                }, Qt::QueuedConnection);
                        }
                        else {
                            // 使用 Notification 替代 QMessageBox::warning
                            QMetaObject::invokeMethod(this, [this, deleteResult]() {
                                if (m_notification) {
                                    m_notification->Push(
                                        Notify_Type_Error,
                                        Pos_Bottom_Right,
                                        "失败",
                                        "删除失败: " + deleteResult.error(),
                                        3000
                                    );
                                }
                                }, Qt::QueuedConnection);
                            qWarning() << "删除最近访问记录失败:" << deleteResult.error();
                        }
                    });
            });
        }, Qt::QueuedConnection);
}

void PageService::onLabelItemClicked(int row)
{
    if (!m_codeEditor) {
        qWarning() << "CodeEditor未设置";
        return;
    }

    qDebug() << "点击标签，跳转到行:" << row;

    bool success = m_codeEditor->scrollToLine(row, true);

    if (success) {
        qDebug() << "成功滚动到第" << row << "行";
    }
    else {
        qWarning() << "滚动到第" << row << "行失败";
    }
}

void PageService::onAddLabelClicked(int row)
{
    if (m_currentFileId.isNull()) {
        // 使用 Notification 替代 QMessageBox::warning
        if (m_notification) {
            m_notification->Push(
                Notify_Type_Warning,
                Pos_Bottom_Right,
                "提示",
                "请先打开文件",
                3000
            );
        }
        qWarning() << "当前无打开的文件，无法添加标签";
        return;
    }

    qDebug() << "准备为第" << row << "行添加标签";

    bool ok;
    QString labelName = QInputDialog::getText(
        nullptr,
        "添加标签",
        QString("为第 %1 行添加标签:").arg(row),
        QLineEdit::Normal,
        "",
        &ok
    );

    if (ok && !labelName.isEmpty()) {
        qDebug() << "标签名称:" << labelName;
        saveLabelInfo(m_currentFileId, labelName, row);
    }
    else {
        qDebug() << "取消添加标签";
    }
}

void PageService::onLabelDeleteRequested(const QUuid& labelId)
{
    qDebug() << "请求删除标签，ID:" << labelId.toString();

    // 保留 QMessageBox::question，因为需要用户确认
    QMessageBox::StandardButton reply = QMessageBox::question(
        nullptr,
        "确认删除",
        "确定要删除该标签吗?",
        QMessageBox::Yes | QMessageBox::No
    );

    if (reply == QMessageBox::Yes) {
        deleteLabel(labelId);
    }
    else {
        qDebug() << "取消删除标签";
    }
}

void PageService::onLabelRenameRequested(const QUuid& labelId, const QString& newName)
{
    updateLabelName(labelId, newName);
}

void PageService::onChangeLineRequested(const QUuid& fileId, int lineNumber)
{
    updateLabelRowNumber(fileId, lineNumber);
}

void PageService::updateRecentAccess(const QUuid& fileId)
{
    if (fileId.isNull()) {
        qWarning() << "文件ID为空，无法更新访问记录";
        return;
    }

    QDateTime currentTime = QDateTime::currentDateTime();
    QString condition = QString("file_id = '%1'").arg(fileId.toString());

    qDebug() << "更新文件访问时间:" << fileId.toString();

    DbMgr::GetInstance()->select("recent_item", "*", condition, QString(),
        [this, fileId, currentTime](const DbResult& result) {
            if (result.isSuccess() && !result.data().isEmpty()) {
                QUuid recentId = QUuid(result.data().first()["recent_id"].toString());

                QVariantMap values;
                values["access_time"] = currentTime.toString(Qt::ISODate);

                QString updateCondition = QString("recent_id = '%1'").arg(recentId.toString());
                DbMgr::GetInstance()->update("recent_item", values, updateCondition,
                    [this](const DbResult& updateResult) {
                        if (updateResult.isSuccess()) {
                            qDebug() << "访问时间更新成功";
                            loadRecentItems();
                        }
                        else {
                            qWarning() << "访问时间更新失败:" << updateResult.error();
                        }
                    });
            }
            else {
                QUuid recentId = QUuid::createUuid();

                QVariantMap values;
                values["recent_id"] = recentId.toString();
                values["file_id"] = fileId.toString();
                values["access_time"] = currentTime.toString(Qt::ISODate);

                DbMgr::GetInstance()->insert("recent_item", values,
                    [this](const DbResult& insertResult) {
                        if (insertResult.isSuccess()) {
                            qDebug() << "访问记录插入成功";
                            loadRecentItems();
                        }
                        else {
                            qWarning() << "访问记录插入失败:" << insertResult.error();
                        }
                    });
            }
        });
}

void PageService::setAutoRefreshInterval(int milliseconds)
{
    if (milliseconds <= 0) {
        m_refreshTimer->stop();
        qDebug() << "自动刷新已禁用";
    }
    else {
        m_refreshTimer->start(milliseconds);
        qDebug() << "自动刷新间隔设置为:" << milliseconds << "毫秒";
    }
}

void PageService::ensureRecentItemExists(const QUuid& fileId)
{
    if (fileId.isNull()) {
        qWarning() << "文件ID为空";
        return;
    }

    QString condition = QString("file_id = '%1'").arg(fileId.toString());

    DbMgr::GetInstance()->select("recent_item", "*", condition, QString(),
        [this, fileId](const DbResult& result) {
            if (result.isSuccess() && !result.data().isEmpty()) {
                qDebug() << "recent_item 记录已存在，不更新时间";
                loadRecentItems();
            }
            else {
                QUuid recentId = QUuid::createUuid();
                QDateTime currentTime = QDateTime::currentDateTime();

                QVariantMap values;
                values["recent_id"] = recentId.toString();
                values["file_id"] = fileId.toString();
                values["access_time"] = currentTime.toString(Qt::ISODate);

                DbMgr::GetInstance()->insert("recent_item", values,
                    [this](const DbResult& insertResult) {
                        if (insertResult.isSuccess()) {
                            qDebug() << "首次访问，创建 recent_item 记录";
                            loadRecentItems();
                        }
                        else {
                            qWarning() << "创建访问记录失败:" << insertResult.error();
                        }
                    });
            }
        });
}

void PageService::saveLabelInfo(const QUuid& fileId, const QString& labelName, int rowNumber)
{
    QUuid labelId = QUuid::createUuid();

    QVariantMap values;
    values["label_id"] = labelId.toString();
    values["file_id"] = fileId.toString();
    values["label_name"] = labelName;
    values["row_number"] = rowNumber;

    qDebug() << "保存标签:" << labelName << "行号:" << rowNumber;

    DbMgr::GetInstance()->insert("label_item", values,
        [fileId, this, labelName](const DbResult& result) {
            if (result.isSuccess()) {
                qDebug() << "标签保存成功:" << labelName;
                loadLabelsForFile(m_currentFileId);
                updateRecentAccess(fileId);
            }
            else {
                qWarning() << "保存标签失败:" << result.error();
                // 使用 Notification 替代 QMessageBox::warning
                if (m_notification) {
                    m_notification->Push(
                        Notify_Type_Error,
                        Pos_Bottom_Right,
                        "失败",
                        "保存标签失败: " + result.error(),
                        3000
                    );
                }
            }
        });
}

void PageService::updateLabelName(const QUuid& labelId, const QString& newName)
{
    if (labelId.isNull()) {
        qWarning() << "标签ID为空，无法重命名";
        return;
    }
    if (newName.isEmpty()) {
        qWarning() << "新标签名称为空，无法重命名";
        return;
    }

    QVariantMap values;
    values["label_name"] = newName;
    QString condition = QString("label_id = '%1'").arg(labelId.toString());

    qDebug() << "更新标签名称，ID:" << labelId.toString() << "新名称:" << newName;

    DbMgr::GetInstance()->update("label_item", values, condition,
        [this, labelId, newName](const DbResult& result) {
            if (result.isSuccess()) {
                qDebug() << "标签重命名成功:" << newName;
                if (!m_currentFileId.isNull()) {
                    loadLabelsForFile(m_currentFileId);
                    updateRecentAccess(m_currentFileId);
                }
            }
            else {
                qWarning() << "标签重命名失败:" << result.error();
                // 使用 Notification 替代 QMessageBox::warning
                if (m_notification) {
                    m_notification->Push(
                        Notify_Type_Error,
                        Pos_Bottom_Right,
                        "失败",
                        "标签重命名失败: " + result.error(),
                        3000
                    );
                }
            }
        });
}

void PageService::updateLabelRowNumber(const QUuid& labelId, int newRowNumber)
{
    if (labelId.isNull()) {
        qWarning() << "标签ID为空，无法更新行号";
        return;
    }
    if (newRowNumber < 1) {
        qWarning() << "新行号无效，必须大于0";
        return;
    }

    QVariantMap values;
    values["row_number"] = newRowNumber;
    QString condition = QString("label_id = '%1'").arg(labelId.toString());

    qDebug() << "更新标签行号，ID:" << labelId.toString() << "新行号:" << newRowNumber;

    DbMgr::GetInstance()->update("label_item", values, condition,
        [this, labelId, newRowNumber](const DbResult& result) {
            if (result.isSuccess()) {
                qDebug() << "标签行号更新成功:" << newRowNumber;
                if (!m_currentFileId.isNull()) {
                    loadLabelsForFile(m_currentFileId);
                    updateRecentAccess(m_currentFileId);
                }
            }
            else {
                qWarning() << "标签行号更新失败:" << result.error();
                // 使用 Notification 替代 QMessageBox::warning
                if (m_notification) {
                    m_notification->Push(
                        Notify_Type_Error,
                        Pos_Bottom_Right,
                        "失败",
                        "标签行号更新失败: " + result.error(),
                        3000
                    );
                }
            }
        });
}

void PageService::deleteLabel(const QUuid& labelId)
{
    QString condition = QString("label_id = '%1'").arg(labelId.toString());

    qDebug() << "删除标签:" << labelId.toString();

    DbMgr::GetInstance()->deleteRecord("label_item", condition,
        [this, labelId](const DbResult& result) {
            if (result.isSuccess()) {
                qDebug() << "标签删除成功:" << labelId.toString();
                if (!m_currentFileId.isNull()) {
                    loadLabelsForFile(m_currentFileId);
                    updateRecentAccess(m_currentFileId);
                }
            }
            else {
                qWarning() << "删除标签失败:" << result.error();
                // 使用 Notification 替代 QMessageBox::warning
                if (m_notification) {
                    m_notification->Push(
                        Notify_Type_Error,
                        Pos_Bottom_Right,
                        "失败",
                        "删除标签失败: " + result.error(),
                        3000
                    );
                }
            }
        });
}

void PageService::saveLastOpenedFileId(const QUuid& fileId)
{
    if (fileId.isNull()) {
        qWarning() << "文件ID为空，无法保存上次打开记录";
        return;
    }

    QString selectSql = "SELECT file_id FROM last_opened_file WHERE id = 1";
    DbMgr::GetInstance()->executeSql(selectSql, [this, fileId](const DbResult& result) {
        if (result.isSuccess() && !result.data().isEmpty()) {
            QString updateSql = QString("UPDATE last_opened_file SET file_id = '%1' WHERE id = 1")
                .arg(fileId.toString());
            DbMgr::GetInstance()->executeSql(updateSql, [](const DbResult& res) {
                if (res.isSuccess()) {
                    qDebug() << "上次打开文件ID更新成功";
                }
                else {
                    qWarning() << "更新上次打开文件ID失败:" << res.error();
                }
                });
        }
        else {
            QString insertSql = QString("INSERT INTO last_opened_file (id, file_id) VALUES (1, '%1')")
                .arg(fileId.toString());
            DbMgr::GetInstance()->executeSql(insertSql, [](const DbResult& res) {
                if (res.isSuccess()) {
                    qDebug() << "首次保存上次打开文件ID成功";
                }
                else {
                    qWarning() << "插入上次打开文件ID失败:" << res.error();
                }
                });
        }
        });
}

void PageService::loadLastOpenedFile(std::function<void(const QString&)> callback)
{
    QString sql = "SELECT file_id FROM last_opened_file WHERE id = 1";

    DbMgr::GetInstance()->executeSql(sql, [this, callback](const DbResult& result) {
        if (!result.isSuccess() || result.data().isEmpty()) {
            qDebug() << "无上次打开文件记录";
            callback("");
            return;
        }

        QUuid lastFileId = QUuid(result.data().first()["file_id"].toString());
        qDebug() << "加载上次打开文件ID:" << lastFileId.toString();

        QString pathSql = QString("SELECT file_path FROM file_info WHERE file_id = '%1'")
            .arg(lastFileId.toString());

        DbMgr::GetInstance()->executeSql(pathSql, [callback](const DbResult& pathResult) {
            if (pathResult.isSuccess() && !pathResult.data().isEmpty()) {
                QString filePath = pathResult.data().first()["file_path"].toString();
                qDebug() << "加载上次打开文件路径:" << filePath;
                callback(filePath);
            }
            else {
                qDebug() << "未找到上次打开文件的路径";
                callback("");
            }
            });
        });
}

void PageService::ensureFileInDatabase(const QString& filePath, int* processedCount, int totalCount)
{
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        qWarning() << "文件不存在，跳过:" << filePath;
        if (processedCount) {
            (*processedCount)++;
            checkFolderLoadComplete(processedCount, totalCount);
        }
        return;
    }

    QString fileName = fileInfo.fileName();
    QDateTime lastModify = fileInfo.lastModified();
    QString condition = QString("file_path = '%1'").arg(filePath);

    qDebug() << "检查文件是否在数据库中:" << fileName;

    DbMgr::GetInstance()->select("file_info", "*", condition, QString(),
        [this, filePath, fileName, lastModify, processedCount, totalCount](const DbResult& result) {
            if (result.isSuccess() && !result.data().isEmpty()) {
                QUuid fileId = QUuid(result.data().first()["file_id"].toString());
                qDebug() << "文件已存在，ID:" << fileId.toString() << fileName;

                QVariantMap values;
                values["last_modify"] = lastModify.toString(Qt::ISODate);
                QString updateCondition = QString("file_id = '%1'").arg(fileId.toString());

                DbMgr::GetInstance()->update("file_info", values, updateCondition,
                    [this, fileId, fileName, processedCount, totalCount](const DbResult& updateResult) {
                        if (updateResult.isSuccess()) {
                            qDebug() << "文件信息更新成功:" << fileName;
                        }
                        ensureRecentItemExists(fileId);

                        if (processedCount) {
                            (*processedCount)++;
                            checkFolderLoadComplete(processedCount, totalCount);
                        }
                    });
            }
            else {
                QUuid fileId = QUuid::createUuid();
                qDebug() << "创建新文件记录，ID:" << fileId.toString() << fileName;

                QVariantMap values;
                values["file_id"] = fileId.toString();
                values["file_name"] = fileName;
                values["file_path"] = filePath;
                values["last_modify"] = lastModify.toString(Qt::ISODate);

                DbMgr::GetInstance()->insert("file_info", values,
                    [this, fileId, fileName, processedCount, totalCount](const DbResult& insertResult) {
                        if (insertResult.isSuccess()) {
                            qDebug() << "新文件记录创建成功:" << fileName;
                            updateRecentAccess(fileId);
                        }
                        else {
                            qWarning() << "创建文件记录失败:" << insertResult.error() << fileName;
                        }

                        if (processedCount) {
                            (*processedCount)++;
                            checkFolderLoadComplete(processedCount, totalCount);
                        }
                    });
            }
        });
}

void PageService::checkFolderLoadComplete(int* processedCount, int totalCount)
{
    if (*processedCount >= totalCount) {
        qDebug() << "文件夹加载完成，共处理" << totalCount << "个文件";

        loadRecentItems();
        emit folderLoaded(totalCount);

        delete processedCount;

        // 使用 Notification 替代 QMessageBox::information
        if (m_notification) {
            m_notification->Push(
                Notify_Type_Success,
                Pos_Bottom_Right,
                "完成",
                QString("已成功加载文件夹中的 %1 个文件").arg(totalCount),
                3000
            );
        }
    }
}

void PageService::ensureFileInDatabase(const QString& filePath)
{
    ensureFileInDatabase(filePath, nullptr, 0);
}